using Microsoft.AspNetCore.Http;
using UniversalAdminSystem.Application.Common.Interfaces;
using UniversalAdminSystem.Application.FileStorage.DTOs;
using UniversalAdminSystem.Application.FileStorage.Interfaces;
using UniversalAdminSystem.Domian.Core.ValueObjects;
using UniversalAdminSystem.Domian.FileStorage.IRepository;
using UniversalAdminSystem.Domian.FileStorage.ValueObjects;
using File = UniversalAdminSystem.Domian.FileStorage.Aggregates.File;

namespace UniversalAdminSystem.Application.FileStorage.Services;

public class FileAppService : IFileAppService
{
    private readonly IFileRepository _fileRepository;
    private readonly IFileValidationService _fileValidator;
    private readonly IFileStorageService _localfileStorage;
    private readonly IUnitOfWork _unitOfWork;
    private readonly IFileProcessingQueue _fileProcessingQueue;


    public FileAppService(IFileRepository fileRepository, IFileValidationService fileValidator, IFileStorageService localfileStorage, IUnitOfWork unitOfWork, IFileProcessingQueue fileProcessingQueue)
    {
        _fileRepository = fileRepository;
        _fileValidator = fileValidator;
        _localfileStorage = localfileStorage;
        _unitOfWork = unitOfWork;
        _fileProcessingQueue = fileProcessingQueue;
    }

    public async Task<FileUploadResultDto> UploadAsync(IFormFile file)
    {
        try
        {
            using var fileStream = file.OpenReadStream();
            var (isValid, message, format) = _fileValidator.ValidateFile(file.FileName, file.Length, fileStream);
            if (!isValid) throw new Exception($"校验结果: {message}");
            var fileInfo = await _localfileStorage.SaveAsync(file);
            Console.WriteLine("开启事务------------------");
            await _unitOfWork.BeginTransactionAsync();
            var fileEntity = File.Create
            (
                FileName.Create(fileInfo.Name),
                FilePath.Create(fileInfo.FullName),
                FileSize.Create(file.Length),
                FileType.Create(file.ContentType),
                (UserId)Guid.NewGuid(),
                false,
                null
            );
            Console.WriteLine($"文件信息打印---------------");
            Console.WriteLine($"文件名：{fileEntity.Name}");
            Console.WriteLine($"文件url：{fileEntity.Path}");
            Console.WriteLine($"文件大小：{fileEntity.Size}");
            Console.WriteLine($"文件类型：{fileEntity.Type}");
            Console.WriteLine("---------------------------");
            await _fileRepository.AddAsync(fileEntity);
            Console.WriteLine("添加数据成功！");

            // 文件处理任务入队
            await _fileProcessingQueue.EnqueueAsync(new FileProcessingJobDto(
                fileEntity.Id.Value,
                fileInfo.FullName,
                file.ContentType,
                file.Length), CancellationToken.None);
            Console.WriteLine("文件处理任务入队成功！提交事务！");
            await _unitOfWork.CommitAsync();
            Console.WriteLine("提交事务成功！");

            return new FileUploadResultDto
            (
                fileEntity.Id.Value,
                fileInfo.Name,
                fileInfo.FullName,
                file.Length,
                file.ContentType,
                message
            );
        }
        catch (Exception ex)
        {
            Console.WriteLine("添加数据到数据库失败！回滚事务！");
            await _unitOfWork.RollbackAsync();
            return new FileUploadResultDto(Message: ex.Message);
        }
    }

    public async Task<IEnumerable<FileUploadResultDto>> GetList()
    {
        var files = await _fileRepository.GetAllAsync();
        return files.Select(file => new FileUploadResultDto(
            file.Id,
            file.Name,
            file.Path,
            file.Size,
            file.Type
        ));
    }

    public async Task<FileDownloadDto> GetFileById(Guid id)
    {
        var file = await _fileRepository.GetByGuidAsync(id);
        if (file == null)
        {
            throw new FileNotFoundException();
        }
        return new FileDownloadDto(file.Id, file.Name, file.Path, file.Type);
    }

    public async Task RemoveFile(Guid id)
    {
        try
        {
            await _fileRepository.RemoveAsync(id);
        }
        catch (System.Exception)
        {

            throw new Exception("删除异常");
        }

    }
}